package com.bougaga.opensource.scheduler.core.handler;

import com.fasterxml.jackson.annotation.JsonInclude;

import java.io.Serializable;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 任务执行结果
 * 
 * @author bougaga
 * @since 1.0.0
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TaskResult implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /**
     * 是否成功
     */
    private boolean success;
    
    /**
     * 结果消息
     */
    private String message;
    
    /**
     * 结果数据
     */
    private Object data;
    
    /**
     * 异常信息
     */
    private String exception;
    
    /**
     * 执行开始时间
     */
    private LocalDateTime startTime;
    
    /**
     * 执行结束时间
     */
    private LocalDateTime endTime;
    
    /**
     * 执行耗时（毫秒）
     */
    private Long duration;
    
    /**
     * 扩展属性
     */
    private Map<String, Object> properties;
    
    public TaskResult() {
        this.startTime = LocalDateTime.now();
    }
    
    public TaskResult(boolean success, String message) {
        this();
        this.success = success;
        this.message = message;
        this.endTime = LocalDateTime.now();
        this.duration = Duration.between(startTime, endTime).toMillis();
    }
    
    public TaskResult(boolean success, String message, Object data) {
        this(success, message);
        this.data = data;
    }
    
    /**
     * 创建成功结果
     */
    public static TaskResult success(String message) {
        return new TaskResult(true, message);
    }
    
    /**
     * 创建成功结果（带数据）
     */
    public static TaskResult success(String message, Object data) {
        return new TaskResult(true, message, data);
    }
    
    /**
     * 创建失败结果
     */
    public static TaskResult failure(String message) {
        return new TaskResult(false, message);
    }
    
    /**
     * 创建失败结果（带异常）
     */
    public static TaskResult failure(String message, Exception exception) {
        TaskResult result = new TaskResult(false, message);
        result.setException(exception.getMessage());
        return result;
    }
    
    /**
     * 完成执行
     */
    public void finish() {
        this.endTime = LocalDateTime.now();
        this.duration = Duration.between(startTime, endTime).toMillis();
    }
    
    // Getters and Setters
    public boolean isSuccess() {
        return success;
    }
    
    public void setSuccess(boolean success) {
        this.success = success;
    }
    
    public String getMessage() {
        return message;
    }
    
    public void setMessage(String message) {
        this.message = message;
    }
    
    public Object getData() {
        return data;
    }
    
    public void setData(Object data) {
        this.data = data;
    }
    
    public String getException() {
        return exception;
    }
    
    public void setException(String exception) {
        this.exception = exception;
    }
    
    public LocalDateTime getStartTime() {
        return startTime;
    }
    
    public void setStartTime(LocalDateTime startTime) {
        this.startTime = startTime;
    }
    
    public LocalDateTime getEndTime() {
        return endTime;
    }
    
    public void setEndTime(LocalDateTime endTime) {
        this.endTime = endTime;
    }
    
    public Long getDuration() {
        return duration;
    }
    
    public void setDuration(Long duration) {
        this.duration = duration;
    }
    
    public Map<String, Object> getProperties() {
        return properties;
    }
    
    public void setProperties(Map<String, Object> properties) {
        this.properties = properties;
    }
    
    @Override
    public String toString() {
        return "TaskResult{" +
                "success=" + success +
                ", message='" + message + '\'' +
                ", duration=" + duration + "ms" +
                '}';
    }
}
